package nicelee.bilibili;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import nicelee.bilibili.live.RoomDealer;
import nicelee.bilibili.live.domain.RoomInfo;
import nicelee.bilibili.plugin.Plugin;
import nicelee.bilibili.threads.ThCommand;
import nicelee.bilibili.threads.ThMonitor;
import nicelee.bilibili.threads.ThRecord;
import nicelee.bilibili.threads.ThWebcast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.util.List;

/**
 * @Author: ZTQ
 * @Description:
 * @Date: create in 2024/3/28 14:37
 */
public class LuncherMain {


	final static String version = "v2.27.0";
	public static Thread thRecord;
	public static Thread thMonitor;
	public static Thread thCommand;
	public static Thread thWebcast;
	public static String[] roomId = {"339059878593","558878017814","902363240753","339059878593","734352268449","93213153180",""};

	/**
	 * 程序入口
	 *
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException, URISyntaxException {
		HttpRequest request = HttpUtil.createGet("https://live.douyin.com/" + LuncherMain.roomId[0]);
		request.header("authority", "live.douyin.com");
		request.header("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
		request.header("accept-language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6");
		request.header("cache-control", "max-age=0");
		request.header("cookie", "xgplayer_user_id=251959789708; passport_assist_user=Cj1YUtyK7x-Br11SPK-ckKl61u5KX_SherEuuGPYIkLjtmV3X8m3EU1BAGVoO541Sp_jwUa8lBlNmbaOQqheGkoKPOVVH42rXu6KEb9WR85pUw4_qNHfbcotEO-cml5itrJowMBlYXDaB-GDqJwNMxMElMoZUycGhzdNVAT4XxCJ_74NGImv1lQgASIBA3Iymus%3D; n_mh=nNwOatDm453msvu0tqEj4bZm3NsIprwo6zSkIjLfICk; LOGIN_STATUS=1; store-region=cn-sh; store-region-src=uid; sid_guard=b177a545374483168432b16b963f04d5%7C1697713285%7C5183999%7CMon%2C+18-Dec-2023+11%3A01%3A24+GMT; ttwid=1%7C9SEGPfK9oK2Ku60vf6jyt7h6JWbBu4N_-kwQdU-SPd8%7C1697721607%7Cc406088cffa073546db29932058720720521571b92ba67ba902a70e5aaffd5d6; odin_tt=1f738575cbcd5084c21c7172736e90f845037328a006beefec4260bf8257290e2d31b437856575c6caeccf88af429213; __live_version__=%221.1.1.6725%22; device_web_cpu_core=16; device_web_memory_size=8; live_use_vvc=%22false%22; csrf_session_id=38b68b1e672a92baa9dcb4d6fd1c5325; FORCE_LOGIN=%7B%22videoConsumedRemainSeconds%22%3A180%7D; __ac_nonce=0658d6780004b23f5d0a8; __ac_signature=_02B4Z6wo00f01Klw1CQAAIDAXxndAbr7OHypUNCAAE.WSwYKFjGSE9AfNTumbVmy1cCS8zqYTadqTl8vHoAv7RMb8THl082YemGIElJtZYhmiH-NnOx53mVMRC7MM8xuavIXc-9rE7ZEgXaA13; webcast_leading_last_show_time=1703765888956; webcast_leading_total_show_times=1; webcast_local_quality=sd; xg_device_score=7.90435294117647; live_can_add_dy_2_desktop=%221%22; msToken=sTwrsWOpxsxXsirEl0V0d0hkbGLze4faRtqNZrIZIuY8GYgo2J9a0RcrN7r_l179C9AQHmmloI94oDvV8_owiAg6zHueq7lX6TgbKBN6OZnyfvZ6OJyo2SQYawIB_g==; tt_scid=NyxJTt.vWxv79efmWAzT2ZAiLSuybiEOWF0wiVYs5KngMuBf8oz5sqzpg5XoSPmie930; pwa2=%220%7C0%7C1%7C0%22; download_guide=%223%2F20231228%2F0%22; msToken=of81bsT85wrbQ9nVOK3WZqQwwku95KW-wLfjFZOef2Orr8PRQVte27t6Mkc_9c_ROePolK97lKVG3IL5xrW6GY6mdUDB0EcBPfnm8-OAShXzlELOxBBCdiQYIjCGpQ==; IsDouyinActive=false; odin_tt=7409a7607c84ba28f27c62495a206c66926666f2bbf038c847b27817acbdbff28c3cf5930de4681d3cfd4c1139dd557e; ttwid=1%7C9SEGPfK9oK2Ku60vf6jyt7h6JWbBu4N_-kwQdU-SPd8%7C1697721607%7Cc406088cffa073546db29932058720720521571b92ba67ba902a70e5aaffd5d6");
		request.header("referer", "https://live.douyin.com/721566130345?cover_type=&enter_from_merge=web_live&enter_method=web_card&game_name=&is_recommend=&live_type=game&more_detail=&room_id=7317569386624125734&stream_type=vertical&title_type=&web_live_tab=all");
		request.header("upgrade-insecure-requests", "1");
		request.header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0");
		HttpResponse httpResponse = request.executeAsync();
		String cookie = "";
		if (httpResponse.isOk()) {
			String body = httpResponse.body();
			System.out.println(httpResponse);

			System.out.println(body);
			List<String> list = httpResponse.headers().get("Set-Cookie");

			System.out.println(list);
			if (CollectionUtil.isNotEmpty(list)) {
				String s = list.get(0);
				String[] split = s.split(";");
				for (String s1 : split) {
					if (s1.startsWith("ttwid=")) {
						cookie = s1;
					}
				}
			}

		}


//				 args = new String[]{"debug=true&liver=taobao&id=f+tCXMPsLAadwUNKSfVQtQ==&delete=false&check=false"};  			// 清晰度全部可选，可不需要cookie
//				 args = new String[]{"debug=true&liver=taobao&id=YG5WFUDk6wfY/8qtva1blw==&delete=false&check=false"};  			// 清晰度全部可选，可不需要cookie
//				 args = new String[]{"debug=true&liver=bili&id=27128250&delete=false&check=false"};  			// 清晰度全部可选，可不需要cookie
//				args = new String[] {"debug=true&check=false&liver=douyu&id=77721&options=D:\\\\Workspace\\\\config.json&liver=douyu&flv=D:" }; // 清晰度全部可选，但部分高清需要cookie
//				args = new String[] { "debug=true&check=false&liver=kuaishou&id=a74874888&" }; // 清晰度全部可选，可不需要cookie
//				args = new String[]{"debug=true&check=false&liver=huya&id=998"}; 				// 清晰度全部可选，可不需要cookie
//				args = new String[]{"debug=true&check=false&liver=huya2&id=189201"}; 				// 清晰度全部可选，可不需要cookie
//				args = new String[]{"debug=true&check=false&liver=yy&id=1355306560"}; 		// 清晰度全部可选，可不需要cookie
//				args = new String[]{"debug=true&check=true&liver=yy&id=28581146"}; 		// 清晰度全部可选，可不需要cookie
//				args = new String[]{"debug=true&check=true&liver=yy&id=29216766"}; 		// 清晰度全部可选，可不需要cookie
//				args = new String[] { "debug=true&check=true&liver=zhanqi&id=90god" }; 			// 清晰度全部可选，可不需要cookie 90god huashan ydjs
//				args = new String[] { "debug=true&check=true&liver=huajiao&id=278581432&qn=1" }; // 只支持默认清晰度(似乎只有一种清晰度)
//				args = new String[] { "debug=true&check=true&liver=acfun&id=36626547" };
// 				args = new String[]{"debug=true&liver=douyin&id=93213153180&delete=false&check=false"};  			// 清晰度全部可选，需要跳过验证的cookie
		args = new String[]{"debug=true&liver=douyin2&id=" + LuncherMain.roomId[0] + "&delete=false&check=false&saveFolder=E:\\video&plugin=true"};            // 清晰度全部可选，需要跳过验证的cookie
//				args = new String[]{"debug=true&liver=douyin2&id=93213153180&delete=false&check=false"};  			// 清晰度全部可选，需要跳过验证的cookie
		//494388186368
		//https://live.douyin.com/456815963645
		//https://live.douyin.com/79443987472?is_aweme_tied=1
		final Plugin plugin = new Plugin();
		if (args != null && args[0].contains("plugin=true")) {
			try {
				plugin.compile();
				plugin.runBeforeInit(args);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		// 根据参数初始化配置
		Config.init(args);
		if (Config.flagPlugin) {
			try {
				plugin.runAfterInit();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		System.out.println(Config.liver + " 直播录制 version " + version);

		// 如果没有传入房间号，等待输入房间号
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		if (Config.shortId == null) {
			System.out.println("请输入房间号(直播网址是https://xxx.com/xxx，那么房间号就是xxx)");
			String line = reader.readLine();
			Config.shortId = line;
		}

		RoomDealer roomDealer = getRoomDealer(Config.liver);
		if (cookie != null) {
			roomDealer.setCookie(cookie);
		}
		RoomInfo roomInfo = getRoomInfo(roomDealer);
		// 清晰度获取
		// 先使用预设的优先级获取
		if (Config.qnPriority != null) {
			String qnDescs[] = roomInfo.getAcceptQualityDesc();
			boolean findQn = false;
			for (int i = 0; i < Config.qnPriority.length; i++) {
				// 遍历qnDescs, 如果符合要求，则设置清晰度
				for (int j = 0; j < qnDescs.length; j++) {
					if (qnDescs[j].equals(Config.qnPriority[i])) {
						Config.qn = roomInfo.getAcceptQuality()[j];
						findQn = true;
						break;
					}
				}
				if (findQn) {
					break;
				}

			}
		}
		// qn = -1, 使用最高画质
		if ("-1".equals(Config.qn)) {
			Config.qn = roomInfo.getAcceptQuality()[0];
		}
		// 没有获取到清晰度，则提示输入
		if (Config.qn == null) {
			// 输入清晰度后，获得直播视频地址
			System.out.println("请输入清晰度代号(:之前的内容，不含空格)");
			Config.qn = reader.readLine();
		}
		// 检查清晰度的合法性
		boolean qnIsValid = false;
		String validQN[] = roomInfo.getAcceptQuality();
		for (int i = 0; i < validQN.length; i++) {
			if (validQN[i].equals(Config.qn)) {
				qnIsValid = true;
				break;
			}
		}
		if (!qnIsValid) {
			System.err.println("输入的qn值不在当前可获取清晰度列表中");
			System.exit(-1);
		}
		// String url = roomDealer.getLiveUrl(roomInfo.getRoomId(),
		// roomInfo.getAcceptQuality()[0]);

		// 开始录制
		thRecord = new ThRecord(roomDealer, roomInfo, cookie, plugin);
		thRecord.start();
		//----------------------------
		thWebcast = new ThWebcast(roomInfo, cookie);
		thWebcast.start();


		// 输出进度，超过指定大小后重新开始一次
		thMonitor = new ThMonitor(roomDealer);
		thMonitor.start();

		// 接收输入指令，停止录制
		thCommand = new ThCommand(roomDealer, thRecord, reader);
		thCommand.start();

	}

	/**
	 * 获取房间信息，当配置恰当时，将一直轮询，直到获得已经开播的房间信息
	 *
	 * @param roomDealer
	 * @return 房间信息
	 */
	public static RoomInfo getRoomInfo(RoomDealer roomDealer) {
		// 获取房间信息
		RoomInfo rroomInfo = roomDealer.getRoomInfo(Config.shortId);

		if (rroomInfo == null) {
			System.err.println("解析失败！！");
			System.exit(-2);
		}
		// 查看是否在线
		if (rroomInfo.getLiveStatus() != 1) {
			System.out.println("当前没有在直播");
			int retryCntLiveOff = 0;
			if (Config.retryIfLiveOff) {
				while (rroomInfo.getLiveStatus() != 1
						&& (Config.maxRetryIfLiveOff == 0 || Config.maxRetryIfLiveOff > retryCntLiveOff)) {
					retryCntLiveOff++;
					try {
						System.out.println(Config.retryAfterMinutes + "分钟左右后重试");
						Thread.sleep((long) (Config.retryAfterMinutes * 60000));
					} catch (InterruptedException e) {
						break;
					}
					rroomInfo = roomDealer.getRoomInfo(Config.shortId);
					if (rroomInfo == null) {
						System.err.println("解析失败！！");
						System.exit(-2);
					}
				}
			} else {
				System.exit(3);
			}
		}
		return rroomInfo;
	}

	/**
	 * 获取正确的视频录制器
	 *
	 * @param liver
	 * @return
	 */
	private static RoomDealer getRoomDealer(String liver) {
		return RoomDealer.createRoomDealer(liver);
	}

}

